package net.esj.basic.plugins.struts2.resultsupport;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Locale;
import java.util.Properties;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.esj.basic.config.Config;
import net.esj.basic.plugins.freemarker.SpringConfigToFreemarkerManager;
import net.esj.basic.utils.hibe.Hi4JSONUtil;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.config.DefaultSettings;
import org.apache.struts2.dispatcher.StrutsResultSupport;
import org.apache.struts2.views.freemarker.FreemarkerManager;
import org.apache.struts2.views.util.ResourceUtil;
import org.json.JSONException;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.LocaleProvider;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.ValueStack;

import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

/**
 * 将对应的页面文件以json的方式ajax输出到前台
 * @author Administrator
 *
 */
public class JsonViewResult extends FreemarkerUsageResult {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	public static final String JSON_VIEW_PROPERTIES = "json.view.properties";
	
	protected Configuration configuration;
	protected Configuration userConfiguration;

	protected ObjectWrapper wrapper;
	private String pContentType = "text/text";

	protected SpringConfigToFreemarkerManager springConfigToFreemarkerManager;
	
	@Override
	public void doExecute(String location, ActionInvocation invocation) throws IOException, TemplateException{
		
		this.configuration = getConfiguration();
		this.wrapper = getObjectWrapper();
		
		if (!location.startsWith("/")) {
            ActionContext ctx = invocation.getInvocationContext();
            HttpServletRequest req = (HttpServletRequest) ctx
                    .get(ServletActionContext.HTTP_REQUEST);
            String base = ResourceUtil.getResourceBase(req);
            location = base + "/" + location;
        } 
		
		Template template = null;
		try{
			if(canUserConfiguration(invocation)){
				this.userConfiguration = getUserConfiguration();
				template = userConfiguration.getTemplate(location,
						deduceLocale(invocation));
			}
		}catch(Exception e){
			//NOUSE
		}finally{
			if(template==null){
				template = configuration.getTemplate(location,
						deduceLocale(invocation));
			}
		}
		

		TemplateModel model = createModel(invocation);
		
		Writer out = new StringWriter();

		if (preTemplateProcess(template, model)) {
			try {
				template.process(model, out);
				String result = Hi4JSONUtil.toJSONString(out.toString());//转成JSON
				ServletActionContext.getResponse().getWriter().print(result);
			} catch (JSONException e) {
				e.printStackTrace();
			} finally {
				postTemplateProcess(template, model);
			}
		}
	}

	protected void postTemplateProcess(Template template, TemplateModel data)
			throws IOException {
	}

	protected boolean preTemplateProcess(Template template, TemplateModel model)
			throws IOException {
		Object attrContentType = template.getCustomAttribute("content_type");
		if (attrContentType != null) {
			ServletActionContext.getResponse().setContentType(
					attrContentType.toString());
		} else {
			String contentType = getContentType();
			if (contentType == null) {
				contentType = "text/html";
			}
			String encoding = template.getEncoding();
			if (encoding != null) {
				contentType = contentType + "; charset=" + encoding;
			}
			ServletActionContext.getResponse().setContentType(contentType);
		}
		return true;
	}

	protected TemplateModel createModel(ActionInvocation invocation)
			throws TemplateModelException {
		ServletContext servletContext = ServletActionContext
				.getServletContext();
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpServletResponse response = ServletActionContext.getResponse();
		ValueStack stack = ServletActionContext.getContext().getValueStack();
		Object action = null;
		if (invocation != null)
			action = invocation.getAction(); // Added for NullPointException
		return springConfigToFreemarkerManager.buildTemplateModel(stack, action,
				servletContext, request, response, wrapper);
	}

	protected Configuration getConfiguration() throws TemplateException {
		return springConfigToFreemarkerManager.getConfiguration(ServletActionContext
				.getServletContext());
	}

	protected Configuration getUserConfiguration() {
		return springConfigToFreemarkerManager.getUserConfiguration(ServletActionContext
				.getServletContext());
	}

	protected Locale deduceLocale(ActionInvocation invocation) {
		if (invocation.getAction() instanceof LocaleProvider) {
			return ((LocaleProvider) invocation.getAction()).getLocale();
		} else {
			return configuration.getLocale();
		}
	}

	protected ObjectWrapper getObjectWrapper() {
		return configuration.getObjectWrapper();
	}

	public String getContentType() {
		return pContentType;
	}

	public void setContentType(String aContentType) {
		pContentType = aContentType;
	}

	protected Writer getWriter() throws IOException {
		return ServletActionContext.getResponse().getWriter();
	}
	
	@Resource
    public void setSpringConfigToFreemarkerManager(SpringConfigToFreemarkerManager mgr) {
        this.springConfigToFreemarkerManager = mgr;
    } 
	
}
